package datasource

import (
	"errors"
	"gitee.com/kristas/booting-go/framework/core/configure"
	"gitee.com/kristas/booting-go/framework/core/statement/types"
)

func NewDataSource(name ...string) DataSource {
	d := &dataSource{}
	if len(name) > 0 {
		d.name = name[0]
	} else {
		d.name = PropertiesPath
	}
	return d
}

type dataSource struct {
	types.Component
	Drivers []DataSourceDriver `wire:""`
	db      DB
	name    string
}

func (d *dataSource) Bean() string {
	return d.name
}

func (d *dataSource) Init() error {
	var dsp = &DataSourceProperties{}
	err := configure.BindPath(d.Bean(), dsp)
	if err != nil {
		return err
	}
	conn, err := d.buildDBConnection(dsp)
	if err != nil {
		return err
	}
	d.db = conn
	return nil
}

func (d *dataSource) buildDBConnection(properties *DataSourceProperties) (DB, error) {
	for _, driver := range d.Drivers {
		if driver.Type() == properties.Type && driver.Driver() == properties.Driver {
			conn, err := driver.Open(properties)
			if err != nil {
				return nil, err
			}
			return conn, nil
		}
	}
	//TODO: recommend type
	return nil, errors.New("not found matched datasource driver for: " + d.Bean())
}

func (d *dataSource) DB() DB {
	return d.db
}
